﻿using System;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Routing;
    
namespace Gama.Extension
{
    public static partial class HtmlHelperExtensions
    {
        public static ActionLinkBuilder<TController> ActionLinkEx<TController>(this HtmlHelper htmlHelper, Expression<Func<TController, ActionResult>> expression)
            where TController : Controller
        {
            return new ActionLinkBuilder<TController>(htmlHelper, expression);
        }
    }

    public class ActionLinkBuilder<TController> : HtmlElementBuilder
        where TController : Controller
    {
        private Expression<Func<TController, ActionResult>> expression;
        private string innerHtml;

        internal ActionLinkBuilder(HtmlHelper htmlHelper, Expression<Func<TController, ActionResult>> expression)
            : base(htmlHelper)
        {
            this.expression = expression;
        }

        public override string Build()
        {
            var body = this.expression.Body as MethodCallExpression;

            Debug.Assert(body != null); 

            // generate routes
            RouteValueDictionary routes = ControllerExtensions.CreateRoutes<TController>(body);

            // prepare url generator
            var urlHelper = new UrlHelper(this.htmlHelper.ViewContext.RequestContext);

            // create html element
            var anchor = new TagBuilder("a");

            anchor.MergeAttributes(new RouteValueDictionary(this.htmlAttributes));
            anchor.MergeAttribute("href", urlHelper.Action(routes["action"].ToString(), routes["controller"].ToString(), routes));
            anchor.InnerHtml = this.innerHtml;
            
            return anchor.ToString();
        }

        internal ActionLinkBuilder<TController> BindTo(Expression<Func<TController, ActionResult>> expression)
        {
            this.expression = expression;
            this.innerHtml = this.htmlHelper.BuildBindingPath(this.expression);

            return this;
        }

        public ActionLinkBuilder<TController> InnerHtml(string innerHtml)
        {
            this.innerHtml = innerHtml;

            return this;
        }
    }    
}
